#ifdef SERVER_SHOW_LOG
#	include <iostream>
#endif

#include <unistd.h>

#include "../ConnectMsg.h"
#include "Buffer.h"
#include "UserInfoManagement.h"

#include "ServerProcess.h"

using std::vector;
using std::string;

ServerProcess::ServerProcess(const string& dbName)
{
	m_userInfo = new UserInfoManagement(dbName);
	m_serverBuffer.resize(sysconf(_SC_OPEN_MAX), NULL);
}
ServerProcess::~ServerProcess()
{
	MapIter iter = m_serverBuffer.begin();
	MapIter end = m_serverBuffer.end();
	for (; iter != end; ++iter)
	{
		delete *iter;
	}	
}

int ServerProcess::Init(int fd)
{
	Buffer* clientBuffer  = m_serverBuffer[fd];
	if (clientBuffer != NULL)
	{
		clientBuffer->Empty();
	}
	else
	{
		clientBuffer = new Buffer(256);
		m_serverBuffer[fd] = clientBuffer;
	}
	return 1;
}

int ServerProcess::Recive(int sockfd, unsigned char* buffer, size_t size)
{
	Buffer* clientBuffer = 0;
	/*
	BufferMap::iterator iter = m_serverBuffer.find(sockfd);
	if (iter == m_serverBuffer.end())
	{
		clientBuffer = new Buffer(256);
		m_serverBuffer[sockfd] = clientBuffer;
	}
	else
	{
		clientBuffer = (*iter).second;
	}
	*/
	clientBuffer = m_serverBuffer[sockfd];
	if (clientBuffer == NULL)
	{
		clientBuffer = new Buffer(256);
		m_serverBuffer[sockfd] = clientBuffer;
	}
	return clientBuffer->Write(buffer, size);

	/*// analyze the tlvlv structure
	const unsigned char* buf = clientBuffer->GetBuffer();
	if (size <= 1) // just tag
		return -1;
	int usrLength = buf[1];
	if (size <= (2+usrLength)) // less than tlv
		return -1;
	int pwdLength = buf[2+usrLength];
	int totalSize = 3 + usrLength + pwdLength; // tlvlv
	if (size < totalSize) // less than tlvlv
		return -1;
    
	return totalSize;*/
}

int ServerProcess::checkPack(Buffer* buffer)
{
	// analyze the tlvlv structure
	const unsigned char* buf = buffer->GetBuffer();
	size_t size = buffer->Size();
	if (size <= 1) // just tag
		return -1;
	int usrLength = buf[1];
	if (size <= (2+usrLength)) // less than tlv
		return -1;
	int pwdLength = buf[2+usrLength];
	int totalSize = 3 + usrLength + pwdLength; // tlvlv
	if (size < totalSize) // less than tlvlv
		return -1;
    
	return totalSize;
}

// 返回值等于0 未能成包
// 返回值小于0 出错
// 返回值小于size 传入缓冲区太小
// 返回值小于等于size 获得包裹成功
int ServerProcess::GetPack(int sockfd, void* buffer, size_t size)
{
	//BufferMap::iterator iter = m_serverBuffer.find(sockfd);
	Buffer* clientBuffer = m_serverBuffer[sockfd];
	//if (iter == m_serverBuffer.end())
	if (clientBuffer == NULL)
		return -1;
	int packSize = checkPack(clientBuffer);
	if (packSize < 0)
	{
		return 0;
	}
	else if (packSize > size)
	{
		return packSize;
	}
	//clientBuffer = (*iter).second;

	return clientBuffer->Read(buffer, packSize);	
}

int ServerProcess::GetPack(int sockfd, Buffer& buffer)
{
	Buffer* clientBuffer = m_serverBuffer[sockfd];
	if (clientBuffer == NULL)
		return -1;
	int packSize = checkPack(clientBuffer);
	if (packSize < 0)
	{
		return 0;
	}
	
	buffer.Write(*clientBuffer, packSize);

	return packSize;
}

QueryResult ServerProcess::Process(const unsigned char* buffer, size_t size)
{
	ClientMsg type = (ClientMsg)buffer[0];
	int usrLength = buffer[1];
	int pwdLength = buffer[2+usrLength];
	char* usr = new char[usrLength + 1];
	memcpy(usr, buffer+2, usrLength);
	usr[usrLength] = 0;
	char* pwd = new char[pwdLength + 1];
	memcpy(pwd, buffer+3+usrLength, pwdLength);
	pwd[pwdLength] = 0;

	QueryResult result = FAILURE;
	switch (type)
	{
	case LOGIN:
		result = m_userInfo->LoginVerify(usr, pwd);
		break;
	case REGISTER:
		result = m_userInfo->Register(usr, pwd);
		break;
	default:
		break;
	}

#ifdef SERVER_SHOW_LOG
	std::cout << "Type: " << type << std::endl
		<< "Username: " << usr << std::endl
		<< "Password: " << pwd << std::endl
		<< "Result: " << result << std::endl;
#endif
	return result;
}
